package net.goutalk.glcs.module.erpModel.caseErpSupplier.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.yulichang.toolkit.MPJWrappers;
import net.goutalk.glcs.common.annotation.GlcsLog;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.ConventPage;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.VoToColumnUtil;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.service.ICaseErpMaterialService;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.entity.CaseErpSupplier;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.entity.CaseErpSupplyMaterial;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.service.ICaseErpSupplierService;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.service.ICaseErpSupplyMaterialService;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.vo.CaseErpSupplyMaterialExportVo;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.vo.CaseErpSupplyMaterialPageVo;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.workflow.utils.WorkFlowUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.dto.AddCaseErpSupplierMaterialDto;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.dto.CaseErpSupplierMaterialPageDto;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.dto.ImportCaseErpSupplyMaterialDto;
import net.goutalk.glcs.module.erpModel.caseErpSupplier.dto.UpdateCaseErpSupplierMaterialDto;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 供应商供货清单【case_erp_supply_material】 前端控制器
 * </p>
 *
 * @author hnyyzy
 * @since 2023-07-05
 */
@RestController
@RequestMapping(GlobalConstant.CASE_ERP_SUPPLIER + "/caseErpSupplyMaterial")
@Api(value = GlobalConstant.CASE_ERP_SUPPLIER + "/caseErpSupplyMaterial", tags = "供应商供货清单")
@AllArgsConstructor
public class CaseErpSupplyMaterialController {

    private ICaseErpSupplyMaterialService caseErpSupplyMaterialService;

    private ICaseErpSupplierService caseErpSupplierService;

    private ICaseErpMaterialService caseErpMaterialService;

    @GetMapping(value = "/page")
    @ApiOperation("供应商供货清单分页")
    public R page(CaseErpSupplierMaterialPageDto dto) {
        if (ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())) {
            dto.setStartTime(WorkFlowUtil.getStartOfDay(dto.getStartTime()));
            dto.setEndTime(WorkFlowUtil.getEndOfDay(dto.getEndTime()));
        }
        IPage<CaseErpSupplyMaterialPageVo> page = caseErpSupplyMaterialService.selectJoinListPage(ConventPage.getPage(dto), CaseErpSupplyMaterialPageVo.class,
                MPJWrappers.<CaseErpSupplyMaterial>lambdaJoin()
                        .distinct()
                        .orderByDesc(CaseErpSupplyMaterial::getCreateDate)
                        .eq(ObjectUtil.isNotEmpty(dto.getSupplierId()), CaseErpSupplyMaterial::getSupplierId, dto.getSupplierId())
                        .eq(ObjectUtil.isNotEmpty(dto.getState()), CaseErpSupplyMaterial::getState, dto.getState())
                        .between(ObjectUtil.isNotNull(dto.getStartTime()) && ObjectUtil.isNotNull(dto.getEndTime())
                                , CaseErpSupplyMaterial::getCreateDate, dto.getStartTime(), dto.getEndTime())
                        .like(StrUtil.isNotBlank(dto.getName()), CaseErpSupplyMaterial::getName, dto.getName())
                        .selectAs(User::getName, CaseErpSupplyMaterialPageVo::getCreateUserName)
                        .select(CaseErpSupplyMaterial::getId)
                        .select(CaseErpSupplyMaterial.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpSupplyMaterialPageVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, CaseErpSupplyMaterial::getCreateUserId));

        PageOutput<CaseErpSupplyMaterialPageVo> pageOutput = ConventPage.getPageOutput(page);
        return R.ok(pageOutput);
    }

    @PostMapping
    @ApiOperation(value = "新增供应商供货清单")
    public R add(@Valid @RequestBody AddCaseErpSupplierMaterialDto dto) throws JsonProcessingException {
        long count = caseErpSupplyMaterialService.count(Wrappers.<CaseErpSupplyMaterial>query().lambda()
                .eq(CaseErpSupplyMaterial::getCode, dto.getCode())
                .eq(CaseErpSupplyMaterial::getSupplierId,dto.getSupplierId()));
        if (count > 0) {
            return R.error("此物料已经存在！");
        }
        return R.ok(caseErpSupplyMaterialService.add(dto));
    }

    @GetMapping(value = "/info")
    @ApiOperation(value = "根据id查询供应商供货清单信息")
    public R info(@RequestParam Long id) {
        CaseErpSupplyMaterial caseErpSupplyMaterial = caseErpSupplyMaterialService.getById(id);
        if (caseErpSupplyMaterial == null) {
            R.error("找不到此供应商！");
        }
        return R.ok(caseErpSupplyMaterial);
    }

    @PutMapping
    @ApiOperation(value = "修改供应商供货清单信息")
    public R update(@Valid @RequestBody UpdateCaseErpSupplierMaterialDto dto) {
        CaseErpSupplyMaterial caseErpSupplyMaterial = BeanUtil.toBean(dto, CaseErpSupplyMaterial.class);
        caseErpSupplyMaterialService.updateById(caseErpSupplyMaterial);
        return R.ok(true);
    }

    @DeleteMapping
    @ApiOperation(value = "删除")
    @GlcsLog(value = "删除供应商供货清单信息")
    public R delete(@Valid @RequestBody Long id) {
        caseErpSupplyMaterialService.removeById(id);
        return R.ok(true);
    }

    @PostMapping(value = "/export")
    @ApiOperation(value = "导出")
    @GlcsLog(value = "导出表单数据")
    public ResponseEntity<byte[]> exportAll(@Valid @RequestBody Long id) {
        List<CaseErpSupplyMaterialExportVo> caseErpSupplyMaterialExportVoList = caseErpSupplyMaterialService.selectJoinList(CaseErpSupplyMaterialExportVo.class,
                MPJWrappers.<CaseErpSupplyMaterial>lambdaJoin()
                        .distinct()
                        .eq(CaseErpSupplyMaterial::getSupplierId,id)
                        .selectAs(User::getName, CaseErpSupplyMaterialExportVo::getCreatUserName)
                        .select(CaseErpSupplyMaterial::getId)
                        .select(CaseErpSupplyMaterial.class, x -> VoToColumnUtil.fieldsToColumns(CaseErpSupplyMaterialExportVo.class).contains(x.getProperty()))
                        .leftJoin(User.class, User::getId, CaseErpSupplyMaterial::getCreateUserId));
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, CaseErpSupplyMaterialExportVo.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(caseErpSupplyMaterialExportVoList);
        return R.fileStream(bot.toByteArray(), "供应商供货清单" + ExcelTypeEnum.XLSX.getValue());
    }

    @PostMapping("/import")
    @ApiOperation(value = "导入")
    public R importData(@RequestParam MultipartFile file) throws IOException {
        List<ImportCaseErpSupplyMaterialDto> savedDataList = EasyExcel.read(file.getInputStream()).head(ImportCaseErpSupplyMaterialDto.class).sheet().doReadSync();
        List<AddCaseErpSupplierMaterialDto> addCaseErpSupplierMaterialDtoList = new ArrayList<>();
        List<CaseErpSupplier> caseErpSupplierList = caseErpSupplierService.list();
        if (CollectionUtil.isNotEmpty(savedDataList)) {
            for (ImportCaseErpSupplyMaterialDto importCaseErpSupplyMaterialDto : savedDataList) {
                AddCaseErpSupplierMaterialDto addCaseErpSupplierMaterialDto = BeanUtil.toBean(importCaseErpSupplyMaterialDto, AddCaseErpSupplierMaterialDto.class);
                if (StrUtil.isNotBlank(importCaseErpSupplyMaterialDto.getSupplierName())) {
                    CaseErpSupplier caseErpSupplier = caseErpSupplierList.stream().filter(x -> x.getName().equals(importCaseErpSupplyMaterialDto.getSupplierName())).findFirst().orElse(new CaseErpSupplier());
                    if (ObjectUtil.isNotEmpty(caseErpSupplier.getName())) {
                        addCaseErpSupplierMaterialDto.setSupplierId(caseErpSupplier.getId());
                        addCaseErpSupplierMaterialDtoList.add(addCaseErpSupplierMaterialDto);
                    } else {
                        return R.error("此供应商名称有误");
                    }
                }
            }
        }
        List<CaseErpSupplyMaterial> caseErpSupplyMaterialList = BeanUtil.copyToList(addCaseErpSupplierMaterialDtoList, CaseErpSupplyMaterial.class);
        caseErpSupplyMaterialService.saveBatch(caseErpSupplyMaterialList);
        return R.ok(true);
    }

    @GetMapping("/export")
    @ApiOperation(value = "下载模板")
    @SneakyThrows
    public ResponseEntity<byte[]> export() {
        List<ImportCaseErpSupplyMaterialDto> importCaseErpSupplyMaterialDtoList = new ArrayList<>();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, ImportCaseErpSupplyMaterialDto.class).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(BeanUtil.copyToList(importCaseErpSupplyMaterialDtoList, ImportCaseErpSupplyMaterialDto.class));
        return R.fileStream(bot.toByteArray(), "供应商供货清单模板" + ExcelTypeEnum.XLSX.getValue());
    }
}
